package com.hooker.common;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ReflectA {
    public ReflectA() {
    }

    public static ReflectA.ReflectMethod method(Class<?> cls, String name, Class<?>... args) throws NoSuchMethodException {
        return new ReflectA.ReflectMethod(getInnerMethod(cls, name, args));
    }

    public static ReflectA.ReflectMethod method(Object host, String name, Class<?>... args) throws NoSuchMethodException {
        return new ReflectA.ReflectMethod(getInnerMethod(host.getClass(), name, args));
    }

    public static ReflectA.ReflectMethod method(String host, String name, Class<?>... args) throws NoSuchMethodException, ClassNotFoundException {
        return new ReflectA.ReflectMethod(getInnerMethod(Class.forName(host), name, args));
    }

    public static ReflectA.ReflectField field(Class<?> cls, String name) throws NoSuchFieldException {
        return new ReflectA.ReflectField(getInnerField(cls, name));
    }

    public static Field getInnerField(Class<?> obj, String name) {
        Class cls = obj;

        while(cls != null) {
            try {
                return cls.getDeclaredField(name);
            } catch (Exception var4) {
                cls = cls.getSuperclass();
            }
        }

        return null;
    }

    public static Method getInnerMethod(Class<?> obj, String name, Class<?>... clsArray) {
        Class cls = obj;

        while(cls != null) {
            try {
                return cls.getDeclaredMethod(name, clsArray);
            } catch (Exception var5) {
                cls = cls.getSuperclass();
            }
        }

        return null;
    }

    public static <T> T get(Object host, String name) {
        try {
            return (T)field(host.getClass(), name).setAccessible(true).get(host);
        } catch (InvocationTargetException var3) {

        } catch (Exception var4) {

        }

        return null;
    }

    public static <T> T get(String host, String name) {
        try {
            return (T)field(Class.forName(host), name).setAccessible(true).get(host);
        } catch (InvocationTargetException var3) {

        } catch (Exception var4) {

        }

        return null;
    }

    public static <T> T get(Class<?> host, String name) {
        try {
            return (T)field(host, name).setAccessible(true).get((Object)null);
        } catch (InvocationTargetException var3) {

        } catch (Exception var4) {

        }

        return null;
    }

    public static void set(Class<?> host, String name, Object value) {
        try {
            field(host, name).setAccessible(true).set((Object)null, value);
        } catch (InvocationTargetException var4) {

        } catch (Exception var5) {

        }

    }

    public static void set(String host, String name, Object value) {
        try {
            field(Class.forName(host), name).setAccessible(true).set((Object)null, value);
        } catch (InvocationTargetException var4) {

        } catch (Exception var5) {

        }

    }

    public static void set(Object host, String name, Object value) {
        try {
            field(host.getClass(), name).setAccessible(true).set(host, value);
        } catch (InvocationTargetException var4) {

        } catch (Exception var5) {

        }

    }

    public static boolean setAll(Object host, String name, Object value) {
        Class<?> cls = host.getClass();

        boolean _isSet;
        for(_isSet = false; cls != null; cls = cls.getSuperclass()) {
            try {
                field(cls, name).setAccessible(true).set(host, value);
                _isSet = true;
            } catch (Exception var6) {
            }
        }

        return _isSet;
    }

    public static Iterable<Field> findFields(Class<?> cls, ReflectA.FieldFilter filter) {
        List<Field> fileds = new ArrayList();
        Iterator var3 = getFields(cls).iterator();

        while(true) {
            Field field;
            do {
                if (!var3.hasNext()) {
                    return fileds;
                }

                field = (Field)var3.next();
            } while(filter != null && !filter.accept(field));

            fileds.add(field);
        }
    }

    private static Iterable<Field> getFields(Class<?> cls) {
        List<Field> fields = new ArrayList();

        for(Class clazz = cls; clazz != null; clazz = clazz.getSuperclass()) {
            Field[] var3 = clazz.getDeclaredFields();
            int var4 = var3.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                Field field = var3[var5];
                fields.add(field);
            }
        }

        return fields;
    }

    public static class ReflectField {
        private Field _field;

        public ReflectField(Field field) {
            this._field = field;
        }

        public ReflectA.ReflectField setAccessible(boolean flag) {
            this._field.setAccessible(flag);
            return this;
        }

        public void set(Object host, Object arg) throws InvocationTargetException, IllegalAccessException {
            this._field.set(host, arg);
        }

        public Object get(Object host) throws InvocationTargetException, IllegalAccessException {
            return this._field.get(host);
        }
    }

    public static class ReflectMethod {
        private Method _method;

        public ReflectMethod(Method method) {
            this._method = method;
        }

        public ReflectA.ReflectMethod accessible(boolean flag) {
            this._method.setAccessible(flag);
            return this;
        }

        public Object call(Object host, Object... args) throws InvocationTargetException, IllegalAccessException {
            return this._method.invoke(host, args);
        }

        public Object invokeNoException(Object host, Object... args) {
            try {
                return this.call(host, args);
            } catch (Exception var4) {

                return null;
            }
        }
    }

    public interface FieldFilter {
        boolean accept(Field var1);
    }
}
